{
 "metadata": {
  "signature": "sha256:30b7328433c550a5338b3869c08948c4f6d3ad01157dd5a1fa942f2f3b9b1645"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Smoothing of a 1D signal\n",
      "========================\n",
      "\n",
      "This method is based on the convolution of a scaled window with the\n",
      "signal. The signal is prepared by introducing reflected window-length\n",
      "copies of the signal at both ends so that boundary effect are minimized\n",
      "in the beginning and end part of the output signal.\n",
      "\n",
      "Code\n",
      "----"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import numpy\n",
      "\n",
      "def smooth(x,window_len=11,window='hanning'):\n",
      "    \"\"\"smooth the data using a window with requested size.\n",
      "    \n",
      "    This method is based on the convolution of a scaled window with the signal.\n",
      "    The signal is prepared by introducing reflected copies of the signal \n",
      "    (with the window size) in both ends so that transient parts are minimized\n",
      "    in the begining and end part of the output signal.\n",
      "    \n",
      "    input:\n",
      "        x: the input signal \n",
      "        window_len: the dimension of the smoothing window; should be an odd integer\n",
      "        window: the type of window from 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'\n",
      "            flat window will produce a moving average smoothing.\n",
      "\n",
      "    output:\n",
      "        the smoothed signal\n",
      "        \n",
      "    example:\n",
      "\n",
      "    t=linspace(-2,2,0.1)\n",
      "    x=sin(t)+randn(len(t))*0.1\n",
      "    y=smooth(x)\n",
      "    \n",
      "    see also: \n",
      "    \n",
      "    numpy.hanning, numpy.hamming, numpy.bartlett, numpy.blackman, numpy.convolve\n",
      "    scipy.signal.lfilter\n",
      " \n",
      "    TODO: the window parameter could be the window itself if an array instead of a string\n",
      "    NOTE: length(output) != length(input), to correct this: return y[(window_len/2-1):-(window_len/2)] instead of just y.\n",
      "    \"\"\" \n",
      "     \n",
      "    if x.ndim != 1:\n",
      "        raise ValueError, \"smooth only accepts 1 dimension arrays.\"\n",
      "\n",
      "    if x.size < window_len:\n",
      "        raise ValueError, \"Input vector needs to be bigger than window size.\"\n",
      "        \n",
      "\n",
      "    if window_len<3:\n",
      "        return x\n",
      "    \n",
      "    \n",
      "    if not window in ['flat', 'hanning', 'hamming', 'bartlett', 'blackman']:\n",
      "        raise ValueError, \"Window is on of 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'\"\n",
      "    \n",
      "\n",
      "    s=numpy.r_[x[window_len-1:0:-1],x,x[-2:-window_len-1:-1]]\n",
      "    #print(len(s))\n",
      "    if window == 'flat': #moving average\n",
      "        w=numpy.ones(window_len,'d')\n",
      "    else:\n",
      "        w=eval('numpy.'+window+'(window_len)')\n",
      "    \n",
      "    y=numpy.convolve(w/w.sum(),s,mode='valid')\n",
      "    return y    \n",
      "\n",
      "    \n",
      "    \n",
      "    \n",
      "from numpy import *\n",
      "from pylab import *\n",
      "    \n",
      "def smooth_demo():    \n",
      "    \n",
      "    t=linspace(-4,4,100)\n",
      "    x=sin(t)\n",
      "    xn=x+randn(len(t))*0.1\n",
      "    y=smooth(x)\n",
      "    \n",
      "    ws=31\n",
      "    \n",
      "    subplot(211)\n",
      "    plot(ones(ws))\n",
      "    \n",
      "    windows=['flat', 'hanning', 'hamming', 'bartlett', 'blackman']\n",
      "    \n",
      "    hold(True)\n",
      "    for w in windows[1:]:\n",
      "        eval('plot('+w+'(ws) )')\n",
      "    \n",
      "    axis([0,30,0,1.1])\n",
      "    \n",
      "    legend(windows)\n",
      "    title(\"The smoothing windows\")\n",
      "    subplot(212)\n",
      "    plot(x)\n",
      "    plot(xn)\n",
      "    for w in windows:\n",
      "        plot(smooth(xn,10,w))\n",
      "    l=['original signal', 'signal with noise']\n",
      "    l.extend(windows)\n",
      "    \n",
      "    legend(l)\n",
      "    title(\"Smoothing a noisy signal\")\n",
      "    show()\n",
      "\n",
      "    \n",
      "if __name__=='__main__':\n",
      "    smooth_demo()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Figure\n",
      "------\n",
      "\n",
      "![](files/attachments/SignalSmooth/smoothsignal.jpg)\n",
      "\n",
      "Smoothing of a 2D signal\n",
      "========================\n",
      "\n",
      "Convolving a noisy image with a gaussian kernel (or any bell-shaped\n",
      "curve) blurs the noise out and leaves the low-frequency details of the\n",
      "image standing out.\n",
      "\n",
      "Functions used\n",
      "--------------"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def gauss_kern(size, sizey=None):\n",
      "    \"\"\" Returns a normalized 2D gauss kernel array for convolutions \"\"\"\n",
      "    size = int(size)\n",
      "    if not sizey:\n",
      "        sizey = size\n",
      "    else:\n",
      "        sizey = int(sizey)\n",
      "    x, y = mgrid[-size:size+1, -sizey:sizey+1]\n",
      "    g = exp(-(x**2/float(size)+y**2/float(sizey)))\n",
      "    return g / g.sum()\n",
      "\n",
      "def blur_image(im, n, ny=None) :\n",
      "    \"\"\" blurs the image by convolving with a gaussian kernel of typical\n",
      "        size n. The optional keyword argument ny allows for a different\n",
      "        size in the y direction.\n",
      "    \"\"\"\n",
      "    g = gauss_kern(n, sizey=ny)\n",
      "    improc = signal.convolve(im,g, mode='valid')\n",
      "    return(improc)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Example\n",
      "-------"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from scipy import *\n",
      "\n",
      "X, Y = mgrid[-70:70, -70:70]\n",
      "Z = cos((X**2+Y**2)/200.)+ random.normal(size=X.shape)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![](files/attachments/SignalSmooth/noisy.png)"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "blur_image(Z, 3)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![](files/attachments/SignalSmooth/convolved.png)\n",
      "\n",
      "The attachment cookb_signalsmooth.py contains a version of this script with some stylistic cleanup.\n",
      "\n",
      "## See Also\n",
      "\n",
      "[\"Cookbook/FiltFilt\"] which can be used to smooth the data by low-pass filtering and does not delay the signal (as this smoother does).  "
     ]
    }
   ],
   "metadata": {}
  }
 ]
}
